package net.homeip.jcperera.nu.core.dom;

import java.io.Serializable;
import java.util.Hashtable;

import javax.inject.Named;

import net.homeip.jcperera.nu.core.msg.BaseMessage;
import net.homeip.jcperera.nu.core.msg.ErrorMessage;
import net.homeip.jcperera.nu.model.entity.Type;

/**
 * Definition for basic Integrity Check, for Entities to check its integrity against predefined Integrity Checks.
 * 
 * @name Integrity Check class
 * @author julio.c.perera@gmail.com
 * @application nu
 * @since 0.1.0.0
 */

@Named(IntegrityCheck.componentName)
public class IntegrityCheck implements Serializable
{
    // Required to implement Serializable interface
    private static final long   serialVersionUID     = 5466663301725290642L;

    // CoreBase properties, for easy use from other components, as well as logging
    public static final int     runtimeLevel         = 0;
    public static final String  moduleName           = "core";
    public static final String  componentName        = "nu_core_dom_integrity_check";

    private static final String classNameItAppliesTo = Type.class.getName();

    /**
     * This is the method subclasses should override, you should call <code>super.check(objectToCheck)</code> while
     * overriding because this method checks <code>Object</code> being of the proper <code>class</code>.
     * 
     * @param objectToCheck
     *            Object it is always interpreted as type associated to specified className
     */
    public void check(Object objectToCheck) throws BaseMessage
    {
        Hashtable<String, String> extensions = new Hashtable<String, String>();
        extensions.put("%className%", getClassNameItAppliesTo());
        try
        {
            if (Class.forName(getClassNameItAppliesTo()).isInstance(objectToCheck))
            {
                extensions.put("%passedClassName%", objectToCheck.getClass().getName());
                throw new ErrorMessage("nu.core.dom.integritycheck.class.bad", BaseMessage.FRIENDLINESS_TECHNICAL,
                        extensions);
            }
        }
        catch (ClassNotFoundException exception)
        {
            extensions.put("%description%", exception.toString());
            throw new ErrorMessage("nu.core.dom.integritycheck.class.notfound", BaseMessage.FRIENDLINESS_TECHNICAL,
                    extensions);
        }
    }

    /**
     * className of the Type to which the IntegrityCheck is associated
     */
    public String getClassNameItAppliesTo()
    {
        return classNameItAppliesTo;
    }
}